﻿#include "pch.h"
#include "framework.h"
#include "ICS.h"
#include "ICSDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

	// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CICSDlg 对话框

// 构造函数，初始化子页面并传递所需的指针
CICSDlg::CICSDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_ICS_DIALOG, pParent)
	, m_nOperatorID(-1) // 初始化为未登录
	, m_nOperatorRole(-1) // 初始化为无角色
	, m_coreOpsPage(&m_reader, m_nOperatorRole) // 传递角色
	, m_walletPage(&m_reader, &m_dbManager, this) // 传递角色
	, m_databasePage(&m_dbManager, this)// 将主窗口指针传给数据库页
	, m_libraryPage(&m_reader, &m_dbManager, m_nOperatorRole) // 传递角色
	, m_accessControlPage(&m_reader, &m_dbManager, m_nOperatorRole) // 传递角色
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

CICSDlg::~CICSDlg()
{
}

void CICSDlg::SetOperator(int operatorId, int operatorRole, const CString& operatorName)
{
	m_nOperatorID = operatorId;
	m_nOperatorRole = operatorRole;
	CString title;
	title.Format(_T("ICS 校园一卡通管理系统 - 操作员: %s"), operatorName);
	SetWindowText(title);

	// 登录状态改变，立即检查所有Tab的锁定状态
	CheckAndUnlockTabs();
}

void CICSDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TAB_MAIN, m_tabMain);
}
BEGIN_MESSAGE_MAP(CICSDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_MAIN, &CICSDlg::OnTcnSelchangeTabMain)
END_MESSAGE_MAP()


// CICSDlg 消息处理程序

BOOL CICSDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);
	// ---- 1. 添加所有Tab标签 ----
	m_tabMain.InsertItem(0, _T("数据库管理"));
	m_tabMain.InsertItem(1, _T("核心操作"));
	m_tabMain.InsertItem(2, _T("钱包功能"));
	m_tabMain.InsertItem(3, _T("图书借阅"));
	m_tabMain.InsertItem(4, _T("门禁控制"));

	// ---- 2. 创建所有子对话框页面 ----
	m_databasePage.Create(IDD_TAB_DATABASE, &m_tabMain);
	m_coreOpsPage.Create(IDD_TAB_CORE_OPS, &m_tabMain);
	m_walletPage.Create(IDD_TAB_WALLET, &m_tabMain);
	m_libraryPage.Create(IDD_TAB_LIBRARY, &m_tabMain);
	m_accessControlPage.Create(IDD_TAB_ACCESS_CONTROL, &m_tabMain);

	// ---- 3. 根据子页面的大小，反向调整主窗口和Tab控件的尺寸 ----
	CRect rcPage;
	// 获取第一个子页面（数据库管理）的尺寸，所有子页面应在资源编辑器中设计为同样大小
	m_databasePage.GetWindowRect(&rcPage);

	// rcPage现在包含了子页面的像素尺寸。我们需要一个同样大小的矩形来计算Tab控件所需空间。
	CRect rcTab;
	rcTab.right = rcPage.Width();
	rcTab.bottom = rcPage.Height();

	// 计算Tab控件为了容纳rcTab这么大的内容区域，自身需要多大（加上标签栏）
	m_tabMain.AdjustRect(TRUE, &rcTab);

	// 为Tab控件和主窗口之间设置边距
	int nMargin = 7;

	// 计算主对话框客户区需要多大才能容纳下计算好的Tab控件和边距
	CRect rcClient;
	rcClient.left = rcClient.top = 0;
	rcClient.right = rcTab.Width() + nMargin * 2;
	rcClient.bottom = rcTab.Height() + nMargin * 2;

	// 根据客户区大小，反向计算出整个窗口（包含标题栏和边框）需要多大
	// 注意：主对话框没有菜单，所以第三个参数是FALSE
	::AdjustWindowRect(&rcClient, GetStyle(), FALSE);

	// 设置主对话框的最终尺寸并将其居中
	SetWindowPos(NULL, 0, 0, rcClient.Width(), rcClient.Height(), SWP_NOMOVE | SWP_NOZORDER);
	CenterWindow();

	// ---- 4. 在调整好尺寸的主窗口中，正确定位Tab控件和所有子页面 ----
	CRect rcMainClient;
	GetClientRect(&rcMainClient); // 获取主窗口客户区的最终尺寸

	// 将Tab控件放置在主窗口客户区中央（带边距）
	m_tabMain.SetWindowPos(NULL, nMargin, nMargin, rcMainClient.Width() - nMargin * 2, rcMainClient.Height() - nMargin * 2, SWP_NOZORDER);

	// 获取Tab控件内部用于显示页面的区域
	CRect rcTabDisplay;
	m_tabMain.GetClientRect(&rcTabDisplay);
	m_tabMain.AdjustRect(FALSE, &rcTabDisplay);

	// 将所有子页面移动到该区域，注意：只移动位置，不改变大小 (SWP_NOSIZE)
	m_databasePage.SetWindowPos(NULL, rcTabDisplay.left, rcTabDisplay.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	m_coreOpsPage.SetWindowPos(NULL, rcTabDisplay.left, rcTabDisplay.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	m_walletPage.SetWindowPos(NULL, rcTabDisplay.left, rcTabDisplay.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	m_libraryPage.SetWindowPos(NULL, rcTabDisplay.left, rcTabDisplay.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	m_accessControlPage.SetWindowPos(NULL, rcTabDisplay.left, rcTabDisplay.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	// ---- 5. 设置初始显示的Tab并锁定/解锁 ----
	m_tabMain.SetCurSel(0); // 默认显示第一个Tab
	OnTcnSelchangeTabMain(nullptr, nullptr); // 手动调用一次切换函数来显示正确的页面
	CheckAndUnlockTabs(); // 调用一次以设置初始状态

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CICSDlg::CheckAndUnlockTabs()
{
	bool isReaderReady = m_reader.IsConnected();
	//bool isDbReady = m_dbManager.IsConnected(); 取消在线数据库的检查
	bool isLoggedIn = (m_nOperatorID != -1); // 检查是否已登录

	if (isReaderReady /*&& isDbReady*/ && isLoggedIn)
	{
		// 全部就绪，解锁所有Tab
		for (int i = 0; i < m_tabMain.GetItemCount(); ++i)
		{
			TCITEM item;
			TCHAR buffer[256];
			item.mask = TCIF_TEXT | TCIF_PARAM;
			item.pszText = buffer;
			item.cchTextMax = 256;
			m_tabMain.GetItem(i, &item);
			item.lParam = 1; // 1 表示启用
			m_tabMain.SetItem(i, &item);
		}
		SetWindowText(_T("ICS 校园一卡通管理系统"));
	}
	else
	{
		// 未就绪，锁定业务Tab
		for (int i = 0; i < m_tabMain.GetItemCount(); ++i)
		{
			TCITEM item;
			TCHAR buffer[256];
			item.mask = TCIF_TEXT | TCIF_PARAM;
			item.pszText = buffer;
			item.cchTextMax = 256;
			m_tabMain.GetItem(i, &item);
			// 只允许访问前两个Tab
			item.lParam = (i < 2) ? 1 : 0; // 0 表示禁用
			m_tabMain.SetItem(i, &item);
		}
		SetWindowText(_T("ICS - 请先连接设备并登录"));

		// 如果当前选中的是后面被禁用的tab，则切换回第一个
		if (m_tabMain.GetCurSel() >= 2)
		{
			MessageBox(_T("请先连接设备并登录"), _T("返回连接页面"), MB_ICONERROR);
			m_tabMain.SetCurSel(0);
			OnTcnSelchangeTabMain(nullptr, nullptr); // 手动触发切换显示
		}
	}
	m_tabMain.Invalidate(); // 刷新Tab控件以显示禁用状态
}


void CICSDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

void CICSDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this);
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CICSDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

//// OnTcnSelchangeTabMain 函数中，在切换时也调用子页面的状态更新
void CICSDlg::OnTcnSelchangeTabMain(NMHDR* pNMHDR, LRESULT* pResult)
{
	// 检查选中的Tab是否被禁用
	int iCurSel = m_tabMain.GetCurSel();
	if (iCurSel != -1)
	{
		TCITEM item;
		item.mask = TCIF_PARAM;
		m_tabMain.GetItem(iCurSel, &item);
		if (item.lParam == 0) // 如果lParam为0，表示禁用
		{
			// 阻止切换，可以切换回上一个或者第一个
			MessageBox(_T("请先连接设备和数据库"), _T("返回连接页面"), MB_ICONERROR);
			if (pResult) *pResult = TRUE; // 阻止切换
			return;
		}
	}

	m_databasePage.ShowWindow(SW_HIDE);
	m_coreOpsPage.ShowWindow(SW_HIDE);
	m_walletPage.ShowWindow(SW_HIDE);
	m_libraryPage.ShowWindow(SW_HIDE);
	m_accessControlPage.ShowWindow(SW_HIDE);

	switch (iCurSel)
	{
	case 0:
		m_databasePage.ShowWindow(SW_SHOW);
		m_databasePage.UpdateStatus();
		break;
	case 1:
		m_coreOpsPage.ShowWindow(SW_SHOW);
		break;
	case 2:
		m_walletPage.ShowWindow(SW_SHOW);
		m_walletPage.UpdateConnectionState();
		m_walletPage.UpdateUIByState(); // 切换时更新
		break;
	case 3:
		m_libraryPage.ShowWindow(SW_SHOW);
		m_libraryPage.UpdateConnectionState();
		m_walletPage.UpdateUIByState(); // 切换时更新
		break;
	case 4:
		m_accessControlPage.ShowWindow(SW_SHOW);
		m_accessControlPage.UpdateConnectionState();
		m_walletPage.UpdateUIByState(); // 切换时更新
		break;
	}

	if (pResult) *pResult = 0;
}

// 新增函数，用于通知所有子页面刷新状态
void CICSDlg::NotifyStateChange()
{
	// 检查登录状态并锁定/解锁Tabs
	CheckAndUnlockTabs();

	// 更新所有子页面的UI状态
	m_walletPage.UpdateUIByState();
	m_libraryPage.UpdateUIByState();
	m_accessControlPage.UpdateUIByState();
	// m_coreOpsPage 如果也需要，可以添加
}
